#ifndef _DOUBLELINKLIST_H_
#define _DOUBLELINKLIST_H_

#include <iostream>
#include <cstdbool>
#define ElementType void*

#define INITDLLIST(list) DLlist list;DoubleLinkNode::DoubleLinkNode(&list);


typedef void (*ClearCallback)(void*);

// 节点类
class DoubleLinkNode 
{
public:
    ElementType data; // 数据域
    DoubleLinkNode *next; // 后驱节点指针
    DoubleLinkNode *prev; // 前驱节点指针
    // 构造函数
    DoubleLinkNode(ElementType data = NULL, DoubleLinkNode *next = NULL, DoubleLinkNode *prev = NULL);

private:

};
typedef class DoubleLinkNode DLNode;


// 双向链表类
class DoubleLinkList 
{
public:
    DoubleLinkNode *head; // 链表头节点指针
    DoubleLinkNode *tail; // 链表尾指针
    int len; // 链表长度

    friend class DoubleLinkNode;
    DoubleLinkList();
    // 尾插法
    void InsertDLlistTail(ElementType element); 
    // 头插法
    void InsertDLlistHead(ElementType element);
    // 按位置删除
    void RemoveByIndex(int index, void (*freePtr)(ElementType));
    // 按值删除
    void RemoveByElement(ElementType element, bool (*OperPtr)(ElementType, ElementType), void (*freePtr)(ElementType));
    // 按位置查找
    ElementType* FindByIndex(int index);
    // 按值查找
    void FindByElement(ElementType element, bool (*OperPtr)(ElementType, ElementType));
    // 遍历
    void TravelDLlist(void(*PrintPtr)(ElementType));
    // 排序
    void DLlistSort(bool (*funcPtr)(ElementType, ElementType));

    void setClearPtr(ClearCallback callback) 
    {
        ClearPtr = callback;
    }
    // 析构函数
    ~DoubleLinkList();
    void ClearDList(void (*ClearPtr)(ElementType));
private:
    ClearCallback ClearPtr;

};
typedef class DoubleLinkList DLlist;
#endif



